import scrapy
import xlwt,xlrd
import time
from datetime import datetime
import pandas as pd
import re
# scrapy runspider myspider.py  运行指令



class WriteExcel():
    def __init__(self,excel_name):
        # 创建一个workbook 设置编码  和worksheet
        self.wb = xlwt.Workbook(encoding='utf-8')
        self.ws_in = self.wb.add_sheet('lib_inside')
        self.ws_out = self.wb.add_sheet('lib_outside')
        self.excel_name = excel_name

    def write_excel_body(self, row, col, value):
        # 数据写入excel,参数对应 行, 列, 值
        self.ws_in.write(row, col, value)  # 不带样式的写入

    def lib_inside_head(self):
        self.ws_in.write(0, 0, '指令')
        self.ws_in.write(0, 1, 'asr文案输入')
        self.ws_in.write(0, 2, 'ws接收asr时刻')
        self.ws_in.write(0, 3, 'asr识别完时刻')
        self.ws_in.write(0, 4, '发起asr接口时刻')
        self.ws_in.write(0, 5, '结束本次流程时刻')
        self.ws_in.write(0, 6, '总耗时')
        self.ws_in.write(0, 7, '闲聊回答')
        self.ws_in.write(0, 8, '中间件返回内容')

    def lib_inside_body(self, count, cmd,asrTextInputTime,wsRevAsrTime,asrIntentTime,asrStartReqTime,endTime,totalCost,part,midWareReturn):
        self.ws_in.write(count, 0, cmd)
        self.ws_in.write(count, 1, asrTextInputTime)
        self.ws_in.write(count, 2, wsRevAsrTime)
        self.ws_in.write(count, 3, asrIntentTime)
        self.ws_in.write(count, 4, asrStartReqTime)
        self.ws_in.write(count, 5, endTime)
        self.ws_in.write(count, 6, totalCost)
        self.ws_in.write(count, 7, part)
        self.ws_in.write(count, 8, midWareReturn)

    def lib_outside_head(self):
        self.ws_out.write(0, 0, '指令')
        self.ws_out.write(0, 1, 'asr文案输入')
        self.ws_out.write(0, 2, 'ws接收asr时刻')
        self.ws_out.write(0, 3, 'asr识别完时刻')
        self.ws_out.write(0, 4, '发起asr接口时刻')
        self.ws_out.write(0, 5, '首次响应时刻')
        self.ws_out.write(0, 6, '总耗时')
        self.ws_out.write(0, 7, '闲聊回答(格式1)')
        self.ws_out.write(0, 8, '闲聊回答(格式2)')
        self.ws_out.write(0, 9, '中间件返回内容')

    def lib_outside_body(self,count,cmd,asrTextInputTime,wsRevAsrTime,asrIntentTime,asrStartReqTime,endTime,totalCost,chartContentStr,RD_text,midWareReturn):
        self.ws_out.write(count, 0, cmd)
        self.ws_out.write(count, 1, asrTextInputTime)
        self.ws_out.write(count, 2, wsRevAsrTime)
        self.ws_out.write(count, 3, asrIntentTime)
        self.ws_out.write(count, 4, asrStartReqTime)
        self.ws_out.write(count, 5, endTime)
        self.ws_out.write(count, 6, totalCost)
        self.ws_out.write(count, 7, chartContentStr)
        self.ws_out.write(count, 8, RD_text)
        self.ws_out.write(count, 9, midWareReturn)

    def save_excel(self):
        current_time = time.strftime("%Y-%m-%d_%H_%M_%S", time.localtime(time.time()))
        self.wb.save('/Users/v_baiguanghui/Downloads/云控相关项目/101.测试脚本/bigScreenDigitalPeople/result/data_{}_{}.xls'.format(self.excel_name,current_time))


class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['file:///Users/v_baiguanghui/Desktop/%E5%A4%A7%E5%B1%8F%E6%95%B0%E5%AD%97%E4%BA%BA/%E7%AB%AF%E5%88%B0%E7%AB%AF/%E9%97%B2%E8%81%8A3.html']
    def parse(self, response):

        writeObj = WriteExcel( '闲聊')
        writeObj.lib_inside_head()
        writeObj.lib_outside_head()

        links = response.css('body > div > details').getall()
        for count in range(1,len(links)+1):
            fullCmd = response.css('body > div > details:nth-child({}) > summary::text'.format(count)).get()
            cmd = response.css('body > div > details:nth-child({}) > summary::text'.format(count)).get().split('：')[1]

            if fullCmd == "指令：" or fullCmd.startswith("指令：{"):    # 语音输入为空或者语音部分格式错误
                continue
            else:
                midWareReturn = response.css(
                    'body > div > details:nth-child({}) > dl > div:nth-child(4) > dd > pre::text'.format(
                        count)).get()
                typeIndex = midWareReturn.find('type')
                typeEndIndex = midWareReturn.find('"', typeIndex + 8)
                if midWareReturn[typeIndex + 8:typeEndIndex] == '闲聊':

                    isAction = midWareReturn.find('"action":')
                    if isAction == -1:  # 向量库外指令
                        asrTextInputTime = response.css(
                            'body > div > details:nth-child({}) > dl > div:nth-child(1) > dt::text'.format(
                                count)).get().split('- ')[1]
                        wsRevAsrTime = response.css(
                            'body > div > details:nth-child({}) > dl > div:nth-child(2) > dt::text'.format(
                                count)).get().split('- ')[1]
                        asrIntentTime = response.css(
                            'body > div > details:nth-child({}) > dl > div:nth-child(2) > dd > pre::text'.format(
                                count)).get().split('"time": ')[1][0:13]
                        asrStartReqTime = response.css(
                            'body > div > details:nth-child({}) > dl > div:nth-child(3) > dt::text'.format(
                                count)).get().split('- ')[1]
                        midWareReturn = response.css(
                            'body > div > details:nth-child({}) > dl > div:nth-child(4) > dd > pre::text'.format(
                                count)).get()

                        divNum = response.css('body > div > details:nth-child({}) > dl > div'.format(count)).getall()
                        data = []
                        resTimeList = []
                        for num in range(5, len(divNum)+1):  # 从 复杂请求发起开始判断
                            rowText = response.css('body > div > details:nth-child({}) > dl > div:nth-child({}) > dt::text'.format(count, num)).get()
                            if "复杂闲聊 数据响应" in rowText:
                                # 拿到响应时间
                                chartContentTime = rowText.split('- ')[1]
                                resTimeList.append(chartContentTime)
                                # 拿到响应内容
                                res = response.css('body > div > details:nth-child({}) > dl > div:nth-child({}) > dd > pre::text'.format(count, num)).get()
                                indexStart = res.find('"data"')
                                indexEnd = res.find('",', indexStart+9)
                                chartContentList = res[indexStart+9:indexEnd:1].replace('\n','')
                                data.append(chartContentList)
                            if "复杂闲聊 完整文本" in rowText:
                                RD_text = response.css('body > div > details:nth-child({}) > dl > div:nth-child({}) > dd::text'.format(count, num)).get()

                        chartContentStr = ''.join(data)
                        data.clear()

                        endTime = resTimeList[0]
                        dt = datetime.strptime(endTime, "%Y/%m/%d %H:%M:%S")
                        timestamp = int(dt.timestamp()) * 1000
                        totalCost = timestamp - int(asrIntentTime)
                        # print(timestamp - asrIntentTime)

                        writeObj.lib_outside_body(count, cmd, asrTextInputTime, wsRevAsrTime, asrIntentTime,
                                             asrStartReqTime, endTime, totalCost, chartContentStr, RD_text,
                                             midWareReturn)

                    else:
                        asrTextInputTime = response.css('body > div > details:nth-child({}) > dl > div:nth-child(1) > dt::text'.format(count)).get().split('- ')[1]
                        wsRevAsrTime = response.css('body > div > details:nth-child({}) > dl > div:nth-child(2) > dt::text'.format(count)).get().split('- ')[1]
                        asrIntentTime = response.css('body > div > details:nth-child({}) > dl > div:nth-child(2) > dd > pre::text'.format(count)).get().split('"time": ')[1][0:13]
                        asrStartReqTime = response.css('body > div > details:nth-child({}) > dl > div:nth-child(3) > dt::text'.format(count)).get().split('- ')[1]
                        midWareReturn = response.css('body > div > details:nth-child({}) > dl > div:nth-child(4) > dd > pre::text'.format(count)).get()
                        endTime = response.css('body > div > details:nth-child({}) > dl > div:nth-child(5) > dt::text'.format(count)).get().split('- ')[1]


                        index_start = midWareReturn.find('"action": "')
                        index_end = midWareReturn.find('"',index_start+11)
                        part= midWareReturn[index_start:index_end:1][11::]
                        # pattern = '^\"action": \".*\"$'
                        # part = re.search(pattern, midWareReturn)[]

                        dt = datetime.strptime(endTime, "%Y/%m/%d %H:%M:%S")
                        timestamp = int(dt.timestamp()) * 1000
                        totalCost = timestamp - int(asrIntentTime)

                        writeObj.lib_inside_body(count, cmd,asrTextInputTime,wsRevAsrTime,asrIntentTime,asrStartReqTime,endTime,totalCost,part,midWareReturn)
        writeObj.save_excel()

if __name__ == '__main__':
    import sys

    if len(sys.argv) > 1:
        start_url = sys.argv[1]
    else:
        start_url = 'file:///Users/v_baiguanghui/Downloads/aaa.html'

    spider = MySpider()
    spider.start_urls = [start_url]
    spider.run()

